/**
 *
 */
package org.hackystat.ui.projectviewer.gwt.client.widgets;

import java.util.List;

import org.hackystat.ui.projectviewer.gwt.client.CSSStyles;
import org.hackystat.ui.projectviewer.gwt.client.controller.ProjectViewerController;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Project list widget. Once initialized, displays the list of projects for configured session.
 * Sources clicks on the project names. Uses {@link ProjectViewerController} as the default
 * listener.
 *
 * @author Pavel Senin
 *
 */
public class ProjectListWidget extends Composite implements ClickListener, SourcesClickEvents {

  final VerticalPanel outer = new VerticalPanel();
  final ListBox projectListBox = new ListBox();
  private final ClickListenerCollection clickListeners = new ClickListenerCollection();
  private ProjectListWidget instance = this;
  private String selection;

  // Project-concious smart buttons panel
  final ProjectActionsWidget projectActionsWidget = new ProjectActionsWidget();
  final CalendarWidget calendarWidget = new CalendarWidget();
  private String action = ProjectActionsWidget.ACTION_VIEW;

  /**
   * Constructor.
   */
  public ProjectListWidget() {
    // register with action listener
    addClickListener(ProjectViewerController.getInstance());
    // back to business
    outer.setStyleName(CSSStyles.PROJECT_LIST_WIDGET_STYLE);
    projectListBox.setVisibleItemCount(6);
    projectListBox.setStyleName(CSSStyles.PROJECT_LIST_STYLE);
    outer.add(projectListBox);
    projectListBox.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        setSelection(projectListBox.getValue(projectListBox.getSelectedIndex()));
        action = ProjectActionsWidget.ACTION_VIEW;
        if (Log.isDebugEnabled()) {
          Log.debug("PLW: intercepted click on list firing action VIEW for" + getSelection());
        }
        clickListeners.fireClick(instance);
      }
    });

    outer.add(projectActionsWidget);
    outer.add(calendarWidget);
    calendarWidget.setVisible(false);
    projectActionsWidget.addClickListener(this);
    initWidget(outer);
  }

  /**
   * Sets the selection into the short-term memory.
   *
   * @param value The selection value.
   */
  private void setSelection(String value) {
    this.selection = value;
  }

  /**
   * Sets the project list.
   *
   * @param index The project list.
   */
  public void setProjectIndex(List<String> index) {
    projectListBox.setEnabled(false);
    projectListBox.clear();
    for (String str : index) {
      projectListBox.addItem(str, str);
    }
    projectListBox.setEnabled(true);
  }

  /**
   * {@inheritDoc}
   */
  public void addClickListener(ClickListener listener) {
    clickListeners.add(listener);
  }

  /**
   * {@inheritDoc}
   */
  public void removeClickListener(ClickListener listener) {
    clickListeners.remove(listener);
  }

  /**
   * Reports selection from the short-term memory.
   *
   * @return The selection.
   */
  public String getSelection() {
    return this.selection;
  }

  /**
   * Sets list enabled/disabled.
   *
   * @param b The value to set.
   */
  public void setEnabled(boolean b) {
    projectListBox.setEnabled(b);
  }

  /**
   * {@inheritDoc}
   */
  public void onClick(Widget sender) {
    if (sender == projectActionsWidget) {
      this.action = projectActionsWidget.getAction();
      if (Log.isDebugEnabled()) {
        Log.debug("PLW: intercepted click fired by PAW, action:" + this.action);
      }
      // figure out if we are going to project diary in here
      if (this.action.equalsIgnoreCase(ProjectActionsWidget.ACTION_DIARY)) {
        calendarWidget.setVisible(true);
      }
      else {
        if (Log.isDebugEnabled()) {
          Log.debug("PLW: firing action outside: " + this.action + "PLW: fire!");
        }
        clickListeners.fireClick(instance);
      }
    }
  }

  /**
   * Reports the action happened.
   *
   * @return The action happened.
   */
  public String getAction() {
    return this.action;
  }

  /**
   * Pops all pushed buttons.
   */
  public void resetButtons() {
    projectActionsWidget.refreshButtons();
  }

}
